package hhq.demo.ctrl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import hhq.demo.config.Conf;
import hhq.demo.mapper.TmpFSMapper;
import hhq.demo.pojo.MyFile;
import hhq.demo.utils.FileUtil;
import hhq.demo.utils.RandomId;
import hhq.demo.utils.ResJson;
import hhq.demo.utils.TimeUitls;

// 文件的 临时存取
@RestController
@RequestMapping(value =  "/fs")
public class TmpFSController {

    @Autowired
    Conf config;

    @Autowired
    TmpFSMapper fileSystemMapper;

    @RequestMapping(value = "/insertFile", method = RequestMethod.POST)
    public String insertFile(HttpServletRequest request
            , @RequestParam("myFile") MultipartFile file
            , @RequestParam("days") String days)
    throws IllegalStateException, IOException 
    {
        clearOvertimeFiles();
        // 如果文件不为空，写入上传路径，进行文件上传
        if (!file.isEmpty()) {

            // 构建上传文件的存放路径
            String path = config.filePath;

            // 获取上传的文件名称，并结合存放路径，构建新的文件名称
            String filename = file.getOriginalFilename();
            //清理非法名称 < > / \ | : " * ?
            filename = FileUtil.clearNotGood(filename);
            File filepath = new File(path, filename);
            System.out.println("HHQ:"+filepath.getAbsolutePath());

            // 判断路径是否存在，不存在则新创建一个
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }

            // 将上传文件保存到目标文件目录
            file.transferTo(new File(path + File.separator + filename));

            int daysN = 1;
            try {
                daysN= Integer.parseInt(days);
            } catch (Exception e) {}
            // 保存为图片
            long overtime = TimeUitls.getNowTime() + Conf.howLongIsOvertime*daysN;
            int id = RandomId.getRandomId();
            MyFile myFile = new MyFile(id, filename, overtime );
            fileSystemMapper.insert(myFile);

            return "<h1>上传成功了！ 取件码是：[ " + id + " ] </h1>";
        } else {
            return "<h1>error</h1>";
        }
    }

    @RequestMapping(value = "/deleteFile")
    public String deleteFile(@RequestParam("code") Integer code) {
        clearOvertimeFiles();
        MyFile myFile = fileSystemMapper.select(code);
        if(  myFile != null ){
            fileSystemMapper.delete( code );
            File file = new File(config.filePath + File.separator + myFile.getName());
            while( file.exists() ){
                file.delete();
            }
            return ResJson.getString(20, "deleteFile succ ! ");
        }else{
            return ResJson.getString(20, "deleteFile failure, because file not exist ！ ");
        }
    }

    @RequestMapping(value = "/indexDownloadFile", method = RequestMethod.GET)
    public void downloadFile(HttpServletResponse response, @RequestParam("code") Integer code) {
        // System.out.println(code);
        clearOvertimeFiles();
        MyFile myFile = fileSystemMapper.select(code); //find file by ID
        File theFIle = new File(config.filePath, myFile.getName());
        // System.out.println(myFile);
        if ( myFile != null && theFIle.exists() && theFIle.isFile() ){ // if file exist in database
            try {
                // response.setContentType("application/octet-stream");
                response.setContentType("application/force-download");
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.setHeader("Pragma", "No-cache");
                response.setHeader("Cache-Control", "No-cache");
                response.setDateHeader("Expires", 0);
                response.setHeader("Content-Disposition", "attachment;fileName="
                     + URLEncoder.encode(myFile.getName(),"UTF-8") ); // insure Chinese correct
                OutputStream out = response.getOutputStream();
                FileInputStream fis=new FileInputStream(theFIle);
                int len = fis.available();
                response.setIntHeader("Content-Length", len); //file size
                byte[] b = new byte[len];
                fis.read(b);
                out.write(b);
                out.flush();
                fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }else{
            try {
                if( ! theFIle.exists())
                    fileSystemMapper.delete(code);
                response.setContentType("text/html; charset=utf-8");
                OutputStream out = response.getOutputStream();
                String mess = "<h1>找不到取件码为N的文件，N="+code+"</h1>";
                byte[] b = mess.getBytes("UTF-8");
                out.write(b);
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
    }

    @RequestMapping(value = "/listFile")
    public String listFile() {
        clearOvertimeFiles();
        List<MyFile> list=fileSystemMapper.selectAllOvertime(Long.MAX_VALUE);
        String html="<h3> 取件码 -------  文件名 ------- 剩余时间</h3>";
        long now = (new Date()).getTime();
        for(MyFile m: list){
            long res = m.getOvertime() - now;
            res /= (1000*60);
            html += "<h5> " + m.getId() + "-------" + m.getName() +
            "-------- " + res + "min"+  "<a href='indexDownloadFile?code="
            + m.getId() + "' target='_blank'>下载</a> </h5>";
        }

        return html;
    }

    private void clearOvertimeFiles(){
        Date date=new Date();
        long now=date.getTime();
        if(now > Conf.timer + Conf.interval){
            Conf.timer = now;
            List<MyFile> list=fileSystemMapper.selectAllOvertime(now);
            System.out.println("一共有N个过期文件, N="+list.size());
            for(MyFile myFile : list){
                fileSystemMapper.delete(myFile.getId());
                File file = new File(config.filePath + File.separator + myFile.getName());
                while( file.exists() ){
                    file.delete();
                }
            }
            System.out.println("删除成功");
        }
    }

}